3.10 Виджеты. Spacer Expanded
4 из 4 шагов пройдено

 Виджеты. Spacer Expanded

➡️ Скачать презентацию. Гибкие Виджеты
➡️ Ссылка на репозиторий с кодом этого урока

Гибкие виджеты Flexible() и Expanded()

Flutter виджеты Row и Column по умолчанию размещают свои дочерние элементы с фиксированными размерами. Это может привести к проблемам, таким как переполнение экрана, если размеры дочерних элементов превышают доступное пространство.

Для решения этой проблемы используются гибкие виджеты Flexible и Expanded.

Фиксированные виджеты имеют неизменные размеры, которые не могут динамически изменяться в зависимости от доступного пространства.

Гибкие виджеты могут изменять свои размеры в зависимости от доступного пространства и свойств flex и fit.

Добавим в файл expanded_widget.dart новый виджет ExpandedExample()

class ExpandedExample extends StatelessWidget {
  const ExpandedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey[400],
      child: Row(
        children: [
        
        ],
      ),
    );
  }
}

⭕ Чтобы отобразить этот виджет на экране, не забудем в main.dart передать в внутри виджета MyApp() в параметр body виджет ExpandedExample()

Для иллюстрации примера гибких виджетов, добавим еще один виджет, который будет представлять из себя цветной прямоугольник.

Добавим в файл expanded_widget.dart новый виджет ColorBox()

class ColorBox extends StatelessWidget {
  final double width, height;
  final Color? color;

  const ColorBox({super.key, 
    required this.width,
    required this.height,
    this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      decoration: BoxDecoration(
        color: color,
      ),
    );
  }
}

Теперь внутри виджета ExpandedExample() в строке Row() вставим три таких штуки и закрасим в разные цвета

class ExpandedExample extends StatelessWidget {
  const ExpandedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey[400],
      child: Row(
        children: [
          ColorBox(width: 100, height: 100, color: Colors.red[400]),
          ColorBox(width: 100, height: 100, color: Colors.green[400]),
          ColorBox(width: 100, height: 100, color: Colors.blue[400]),
        ],
      ),
    );
  }
}


В данном примере мы используем фиксированные виджеты, с жестко заданными размерами. Но чаще всего современные интерфейсы должны адаптироваться под разные размеры экранов и растягивать/сжимать свои элементы, при этом не ломая интерфейс.

Виджет Expanded() позволяет растягивать виджет на всё доступное пространство.
Также игнорирует ширину дочернего элемента при изменении размеров.

Обернем каждый виджет, Зеленый и Синий в виджет Expanded()
В результате у каждого из них ширина равноценного растянется на всё доступное пространство.

class ExpandedExample extends StatelessWidget {
  const ExpandedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey[400],
      child: Row(
        children: [
          ColorBox(width: 100, height: 100, color: Colors.red[400]),
          Expanded(
            child: ColorBox(
              width: 100,
              height: 100,
              color: Colors.green[400],
            ),
          ),
          Expanded(
            child: ColorBox(
              width: 100,
              height: 100,
              color: Colors.blue[400],
            ),
          ),
        ],
      ),
    );
  }
}

 

Если теперь пробовать менять размеры фиксированного красного виджета, то синий и зеленый буду также пропорционально увеличиваться или уменьшаться автоматически. Например, сделаем ширину красного в 300 едениц

Что значит 300 единиц?

Размеры элементов задаются в логических пикселях (logical pixels)
Независимые от устройства пиксели device-independent pixels или dp

Flutter вместо нас, в зависимости от размера экрана, посчитает реальное значение пикселей.

Виджет Expanded() в качестве параметра принимает flex, который указывает долю занимаемого пространства.

Если в Row или Column находятся несколько гибких виджетов, их доли рассчитываются как сумма значений flex.

Например, если у одного виджета flex: 1, а у другого flex: 2, то первый получит 1/3 доступного пространства, а второй — 2/3.

Expanded(
  flex: 1,
  child: ColorBox(
    width: 100,
    height: 100,
    color: Colors.green[400],
  ),
),

Expanded(
  flex: 2,
  child: ColorBox(
    width: 100,
    height: 100,
    color: Colors.blue[400],
  ),
),

 

Flexible

Виджет Flexible делает всё тоже самое, но зависит от параметра fit

  • FlexFit.loose: Виджет сохраняет свои минимальные размеры, но может использовать дополнительное пространство (по умолчанию)

  • FlexFit.tight: Виджет растягивается на всё доступное пространство (Expanded)

    Также игнорирует ширину дочернего элемента при изменении размеров

ColorBox(width: 100, height: 100, color: Colors.red[400]),

Flexible(
  child: ColorBox(
    width: 100,
    height: 100,
    color: Colors.green[400],
  ),
),

Flexible(
  child: ColorBox(
    width: 100,
    height: 100,
    color: Colors.blue[400],
  ),
),


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий